import http from '@/utils/http'

let curToken = null
let curEncryptToken = null
let curAccount = {}

export function getToken () {
	return curToken
}

export function getVerifyToken () {
	return curEncryptToken
}

export function getAccount () {
	return curAccount
}

class DahuaPlayer {
	/**
	 * 大华播放器操作类
	 * @param {Object}    options             公共配置信息
	 * @param {String}    options.el          播放器容器 id, 创建多个播放器时, 传入不同的容器 id 即可
	 * @param {String}    options.staticPath 存放大华云 sdk 的绝对路径
	 * @param {String}    options.protocol    大华云平台服务的请求协议
	 * @param {String}    options.ip          大华云平台服务的请求 ip
	 * @param {String}    options.port        大华云平台服务的请求端口
	 * @param {String}    options.username    用户名
	 * @param {String}    options.password    密码
	 */
	constructor(options = {}) {
		this.player = null
		this.el = options.el ?? 'dahua-player'
		this.options = options
		this.selectIndex = -1
		this.maxPlayerNumber = 1 // 当前可用的窗口数量
		this.initializationCompleted = false
		this.clientInfo = {
			protocol: this.options.protocol ?? 'http',
			ip: this.options.ip,
			port: this.options.port,
			username: this.options.username,
			password: this.options.password
		}
		this.clientInfo.origin = window.localStorage.getItem('wsplayer_origin') || window.sessionStorage.getItem('wsplayer_origin') || `${this.clientInfo.protocol}://${this.clientInfo.ip}:${this.clientInfo.port}`
		this.loopKeepAliveTimer = null
		this.token = window.localStorage.getItem('psi_token') || window.sessionStorage.getItem('psi_token') || null
		this.playerType = {
			1: 'real',
			2: 'record',
			real: 'real',
			record: 'record'
		}

		curAccount = {
			protocol: this.clientInfo.protocol,
		}

		if (this.options.ip) {
			curAccount.ip = this.options.ip
		}

		if (this.options.port) {
			curAccount.port = this.options.port
		}

		if (this.options.username) {
			curAccount.username = this.options.username
		}

		if (this.options.password) {
			curAccount.password = this.options.password
		}

		this.completeResolve = null
	}

	login (callback) {
		clearInterval(this.loopKeepAliveTimer)

    http.get('/common/cameraServer', {}).then(res => {
			if (res.code == 1) {
				this.clientInfo = {
					protocol: 'http',
					ip: res.data.vms_ip,
					port: res.data.vms_port,
					username: res.data.vms_user,
					password: res.data.vms_psw
				}
				this.clientInfo.origin = window.localStorage.getItem('wsplayer_origin') || window.sessionStorage.getItem('wsplayer_origin') || `${this.clientInfo.protocol}://${this.clientInfo.ip}:${this.clientInfo.port}`
				
				this.dahuaLogin(callback)
			}
    })
	}

	// 登录大华云平台
	dahuaLogin(callback) {
		window.sessionStorage.setItem('wsplayer_origin', this.clientInfo.origin)
		window.localStorage.setItem('wsplayer_origin', this.clientInfo.origin)

		clearInterval(this.loopKeepAliveTimer)

		wsplayerLogin({
			origin: this.clientInfo.origin,
			userName: this.clientInfo.username,
			password: this.clientInfo.password
		}).then(data => {
			console.log('🚀 ~ login ~ data:', data)
			this.token = data.token

			curToken = data.token
			curEncryptToken = data.encryptToken

			curAccount = {
				token: curToken,
				encryptToken: curEncryptToken,
				protocol: this.clientInfo.protocol,
				port: this.clientInfo.port,
				ip: this.clientInfo.ip,
				userName: this.clientInfo.username,
				password: this.clientInfo.password
			}

			callback?.(curAccount)

			window.sessionStorage.setItem('psi_token', data.token)
			window.sessionStorage.setItem('wsplayer_username', data.userName)
			window.sessionStorage.setItem('wsplayer_logininfo', JSON.stringify({
				protocol: this.clientInfo.protocol,
				port: this.clientInfo.port,
				ip: this.clientInfo.ip,
				userName: this.clientInfo.username,
				password: this.clientInfo.password
			}))

			window.localStorage.setItem('psi_token', data.token)
			window.localStorage.setItem('wsplayer_username', data.userName)
			window.localStorage.setItem('wsplayer_logininfo', JSON.stringify({
				protocol: this.clientInfo.protocol,
				port: this.clientInfo.port,
				ip: this.clientInfo.ip,
				userName: this.clientInfo.username,
				password: this.clientInfo.password
			}))

			console.log('大华视频云平台登录成功')
			this.loopKeepAlive()
		}).catch(e => {
			console.log(e || 'error')
		})
	}

	/**
	 * 每隔 20 秒，刷一下 token
	 */
	loopKeepAlive() {
		this.loopKeepAliveTimer = setInterval(() => {
			const token = this.token
			const origin = this.clientInfo.origin

			fetch(`/videoService/accounts/token/keepalive`, {
				method: 'PUT',
				headers: {
					'X-Subject-Token': token,
					'Content-Type': 'application/json',
					'Self-TargetOrigin': origin
				},
				body: JSON.stringify({
					token
				})
			}).then(response => response.json()).then(data => {
				// 鉴权失败，移除本地 token 重新登录
				if (data && data.code && [401, 402].includes(data.code)) {
					window.sessionStorage.removeItem('psi_token')
					window.sessionStorage.removeItem('wsplayer_username')
					window.sessionStorage.removeItem('wsplayer_origin')
					window.localStorage.removeItem('psi_token')
					window.localStorage.removeItem('wsplayer_username')
					window.localStorage.removeItem('wsplayer_origin')

					// 3 秒后重连
					setTimeout(() => {
						this.login()
					}, 3000)
				}
			})
		}, 1000 * 20)
	}

	/**
	 * 退出登录
	 */
	logout() {
		clearInterval(this.loopKeepAliveTimer)
		
		const token = this.token
		const origin = this.clientInfo.origin

		if (!token) {
			return
		}

		return fetch('/videoService/accounts/unauthorize', {
			method: 'POST',
			headers: {
				'X-Subject-Token': token,
				'Content-Type': 'application/json',
				'Self-TargetOrigin': origin
			},
			body: JSON.stringify({
				token
			})
		}).then(() => {
			this.token = null

			window.sessionStorage.removeItem('psi_token')
			window.sessionStorage.removeItem('wsplayer_username')
			window.sessionStorage.removeItem('wsplayer_origin')
			window.localStorage.removeItem('psi_token')
			window.localStorage.removeItem('wsplayer_username')
			window.localStorage.removeItem('wsplayer_origin')
		})
	}

	// 根据通道数量，获取需要初始化的数量
	fotmatChannelCount(channelNumber) {
		// 直接返回 [1, 4, 9, 16, 25] 的方案
		// return channelNumber > 0 && channelNumber <= 25
		//   ? Math.pow(Math.ceil(Math.sqrt(channelNumber)), 2)
		//   : -1

		if (channelNumber <= 4) {
			return channelNumber
		} else if (channelNumber > 4 && channelNumber < 9) {
			return channelNumber % 2 === 0 ? channelNumber : channelNumber + 1
		} else if (channelNumber >= 9 && channelNumber <= 25) {
			return Math.pow(Math.ceil(Math.sqrt(channelNumber)), 2)
		} else {
			return -1
		}
	}

	// 根据通道数量，获取可显示的最大数量
	fotmatChannelMax(channelNumber) {
		return channelNumber > 0 && channelNumber <= 25
			? Math.pow(Math.ceil(Math.sqrt(channelNumber)), 2)
			: 25
	}

	/**
	 * 云台控制
	 * 向右 pan 1
	 * 向左 pan -1
	 * 放大 zoom 1
	 * 缩小 zoom -1
	 * 向上 tilt 1
	 * 向下 tilt -1
	 * @param {Object} action 控制命令
	 * @param {Number} action.channelCode   视频通道 code
	 * @param {Number} action.left   向左移动
	 * @param {Number} action.right  向右移动
	 * @param {Number} action.top    向上移动
	 * @param {Number} action.bottom 向下移动
	 * @param {Number} action.zoom   放大 [zoom> 0 放大, zoom < 0 缩小]
	 */
	ptzController(action) {
		const postData = {
			zoom: action.zoom ?? 0,
			tilt: action.tilt ?? 0,
			pan: action.pan ?? 0,
			duration: 100,
			channelId: action.channelCode
		}

		if (action.left) {
			postData.pan = 0 - action.left
		}

		if (action.right) {
			postData.pan = action.right | 0
		}

		if (action.top) {
			postData.tilt = action.top | 0
		}

		if (action.bottom) {
			postData.tilt = 0 - action.bottom
		}

		const token = this.token
		const origin = this.clientInfo.origin

		if (!token) {
			return
		}

		fetch(`/videoService/ptz/${action.channelCode}`, {
			method: 'PUT',
			headers: {
				'X-Subject-Token': token,
				'Content-Type': 'application/json',
				'Self-TargetOrigin': origin
			},
			body: JSON.stringify(postData)
		})
	}

	/**
	 * 云台控制，外部应用
	 * @param {Object} action 控制命令
	 * @param {Number} action.channelCode   视频通道 code
	 * @param {Number} action.left   向左移动
	 * @param {Number} action.right  向右移动
	 * @param {Number} action.top    向上移动
	 * @param {Number} action.bottom 向下移动
	 */
	ptzAction(action) {
		const moveCount = Math.max(action.left | 0, action.right | 0, action.top | 0, action.bottom | 0)
		let moveIndex = 0

		if (action.zoom) {
			ptzController({
				zoom: action.zoom,
				channelCode: action.channelCode
			})
		}

		let loopAction = setInterval(() => {
			if (moveIndex >= moveCount) {
				clearInterval(loopAction)

				return
			}

			ptzController({
				left: --action.left >= 0 ? 1 : 0,
				right: --action.right >= 0 ? 1 : 0,
				top: --action.top >= 0 ? 1 : 0,
				bottom: --action.bottom >= 0 ? 1 : 0,
				channelId: action.channelCode
			})

			moveIndex++
		}, 150)
	}

	/**
	 * 根据预置点，执行云台控制
	 * @param {String} channel 视频通道
	 * @param {Number} index   预置点
	 * @returns 
	 */
	ptzMoveByIndex(channel, index) {
		console.log('🚀 ~ ptzMoveByIndex ~ channel, index:', channel, index)
		const token = this.token
		const origin = this.clientInfo.origin
		console.log('🚀 ~ ptzMoveByIndex ~ token, origin:', token, origin)

		if (!token) {
			return
		}

		fetch(`/videoService/ptz/preset/goto/channels/${channel}/${index}`, {
			method: 'PUT',
			headers: {
				'X-Subject-Token': token,
				'Content-Type': 'application/json',
				'Self-TargetOrigin': origin
			},
			body: JSON.stringify({
				speed: 0.5
			})
		})
	}

	/**
	 * 创建大华播放器实例
	 * 播放实时视频和录像回放的操作，需要解码库的初始化完成，
	 * 在 "receiveMessageFromWSPlayer" 中监听 initializationCompleted 事件
	 * @see https://open-icc.dahuatech.com/wsplayer/#/start
	 * @param {String}    el      需要加载的容器 id 名称
	 * @param {String}    options. 
	 * @param {String}    options.el                           播放器容器 id, 创建多个播放器时, 传入不同的容器 id 即可。 
	 * @param {String}   [options.type='real']                 播放器类型有 [real: 实时预览, record:录像回放] def:real
	 * @param {Number}   [options.maxNum=25]                   最多显示的路数, 可设置 1、4、9、 16、25 等五种路数 def:25
	 * @param {Number}   [options.num=4]                       初始化显示的路数, 可设置 1、2、3、4、6、8、9、 16、25 等, 该值不能超过 maxNum def:4
	 * @param {Boolean}  [options.showControl=true]            是否展示工具栏, def: true
	 * @param {Boolean}  [options.showRecordProgressBar=true]  是否显示录像回放时间轴 def: true
	 * @param {String}   [options.pztEl='']                    云台的容器 id, def: '' (demo 为 'pztEl')
	 * @param {Boolean}  [options.isDynamicLoadLib=true]       是否动态加载解码库, 当动态加载出现一系列问题时, 可以改成静态加载 def true
	 * @param {Boolean}  [options.onlyLoadSingleLib=false]      ?? 是否只加载单线程解码库 ?? (demo里面有但是没有值)
	 * @param {String}   [options.STATIC_PATH='/wsplayer-gov'] 静态资源相对路径, 用于正确获取静态资源路径 def: '/wsplayer-gov'
	 * @param {Boolean}  [options.useNginxProxy=false]         是否使用 nginx 转发流, def false
	 * @param {String}   [options.nginxProxyHost='']           拉取流的代理 host, 需要 useNginxProxy 设置为true, 默认为空, 不填时, 组件获取当前的 host 去拉取流
	 * @param {Boolean}  [options.useWSS=false]                是否使用 wss 直连到转发服务节点, 默认为 false
	 * @param {Boolean}  [options.downloadMp4Record=true]      本地录像是否下载 MP4 格式, 否则下载 dav 格式, 默认为 true
	 * @param {Number}   [options.localRecordSize=100]         本地录像每个文件的大小(正整数), 单位兆(M), 默认为 100
	 * @param {String}   [options.playerAdapter='stretching']  视频自适应类型 [stretching:拉伸, selfAdaption: 自适应], 默认拉伸
	 * @param {String}   [options.picCapName=null]             自定义抓图文件名称, 默认 null
	 * @param {String}   [options.localRecordName=null]        自定义录像文件名称, 默认 null
	 * @param {Boolean}  [options.showIcons]                   值为 boolean 时总控视频上方窗口操作栏按钮是否显示, 默认为都展示, 当参数为 false 时, 则隐藏整个操作栏
	 * @param {Object}   [options.showIcons]                   值为 object 时，按照 Record<key, bool> 控制单个按钮的显示状态
	 * @param {Boolean}  [options.showIcons.streamChangeSelect=true]  主辅码流切换, 默认为 true
	 * @param {Boolean}  [options.showIcons.localRecordIcon=true]     本地录像功能按钮, 默认为 true
	 * @param {Boolean}  [options.showIcons.audioIcon=true]           开启关闭声音按钮, 默认为 true
	 * @param {Boolean}  [options.showIcons.snapshotIcon=true]        抓图按钮, 默认为 true
	 * @param {Boolean}  [options.showIcons.closeIcon=true]           关闭视频按钮, 默认为 true
	 * @param {Object[]} [options.showIcons.extendIcons]              自定义扩展按钮, 参数格式示例:[{className : 'extend', title :'自定义', onClick : (index,channelCode,channelData)=>{}}]
	 * @param {String}   [options.showIcons.extendIcons.className]    自定义按钮使用的样式名称
	 * @param {String}   [options.showIcons.extendIcons.title]        自定义按钮的 hover title
	 * @param {Function} [options.showIcons.extendIcons.onClick]      自定义按钮的回调事件  [index: 当前频道的 index,channelCode,channelData.channelName]
	 * @param {Function} [options.receiveMessageFromWSPlayer]         播放器的事件回调 (type, data)
	 */
	createPlayer(el, options = {}) {
		el = el || this.el || 'dahua-player'

		this.el = el
		this.maxPlayerNumber = options.num

		this.player?.dispose?.()

		this.player = new PlayerManager({
			el: el /** 实时预览容器id, 创建多个播放器, 传入不同的容器id即可 **/,
			type: this.playerType[options.type] || 'real', // real: 实时预览  record: 录像回放
			maxNum: options.maxNum | 0  /** 最多显示的路数, 可根据实际情况设置, 可设置1 4 9 16 25等5种路数 **/,
			num: options.num | 0 /** 初始化显示的路数 **/,
			showControl: options.showControl/** 默认是否显示工具栏 **/,
			showRecordProgressBar: options.showRecordProgressBar,
			pztEl: options.pztEl || '',
			isDynamicLoadLib: options.isDynamicLoadLib,
			onlyLoadSingleLib: options.onlyLoadSingleLib,
			STATIC_PATH: this.options.staticPath ? this.options.staticPath : '/wsplayer-gov', // 静态资源相对路径,用于正确获取静态资源路径
			useNginxProxy: options.useNginxProxy,
			nginxProxyHost: options.nginxProxyHost,
			useWSS: options.useWSS,
			downloadMp4Record: Boolean(options.downloadMp4Record),
			localRecordSize: options.localRecordSize,
			playerAdapter: options.playerAdapter,
			picCapName: options.picCapName ? (index, channelCode, channelData) => {
				return `抓图_第${index + 1}个窗口_channelCode-${channelCode}_channelName-${channelData.channelName}_${Date.now()}`
			} : null,
			localRecordName: options.localRecordName ? (index, channelCode, channelData) => {
				return `录像_第${index + 1}个窗口_channelCode-${channelCode}_channelName-${channelData.channelName}_${Date.now()}`
			} : null,
			showIcons: typeof options.showIcons === 'boolean' && !!options.showIcons
				? {
					streamChangeSelect: true, // 主辅码流切换
					localRecordIcon: true, // 本地录像功能按钮
					audioIcon: true, // 开启关闭声音按钮
					snapshotIcon: true, // 抓图按钮
					closeIcon: true, // 关闭视频按钮
					extendIcons: null
				}
				: Object.assign({
					streamChangeSelect: false, // 主辅码流切换
					localRecordIcon: false, // 本地录像功能按钮
					audioIcon: false, // 开启关闭声音按钮
					snapshotIcon: false, // 抓图按钮
					closeIcon: false, // 关闭视频按钮
					extendIcons: null
				}, options.showIcons),
			/**
			 * 播放器的消息回调
			 * @param {String} type 消息类型，包含以下类型:
			 * initializationCompleted<type>: 动态加载解码库初始化完成
			 * realSuccess<type>: 实时预览成功
			 * realSuccess {"selectIndex":0,"streamServerIp":"192.168.10.5","rtspURL":"rtsp://192.168.10.5:8555/cam/realmonitor?vcuid=10405575109576896&subtype=1&urlType=pull&streamType=0&token=1719545205_99e71fcbe7b59c1caade2f559ece7e83b8785ce8","channelId":"10405575109576896","channelData":{"channelCode":"10405575109576896","isOnline":true,"isPause":false,"channelName":"测试实验室外部门口01","id":"10405575109576896","cameraType":2},"streamType":2,"wsList":["192.168.10.5:8555"],"wsURL":"ws://192.168.10.5:8555","playerAdapter":"stretching"}
			 * realError<type>: 实时预览失败
			 * recordSuccess<type>: 录像回放成功
			 * recordError<type>: 录像回放失败
			 * recordFinish<type>: 录像回放播放完成
			 * statusChanged<type>:视频播放状态改变 {status:['closed'], sindowIndex}
			 * selectWindowChanged<type>: 选中的窗口发生改变
			 * windowNumChanged<type>: 播放器显示路数发生改变
			 * closeVideo<type>: 视频关闭
			 * closeVideo {"selectIndex":1,"changeVideoFlag":false,"channelData":{"channelCode":"10405577221933248","isOnline":true,"isPause":true,"channelName":"测试实验室外部仓库01","id":"10405577221933248","cameraType":2}}
			 * throwCurrentRecordTime<type>: 抛出录像回放时间，对象含有窗口索引、Date 类型录像时间、通道编码 channelCode
			 * switchStartTime<type>: 录像回放点击时间轴回调
			 * @param {String|Object} data  消息的内容
			 */
			receiveMessageFromWSPlayer: (type, data) => {
				// console.log('🚀 ~ DahuaPlayer ~ createPlayer ~ type, data:', type, data)
				switch (type) {
					// 动态加载解码库初始化完成
					case 'initializationCompleted':
						this.initializationCompleted = true
						// 这里需要一个解码库初始化完成后的回调
						break
					// 选中的窗口发生改变 data => {channelId, playIndex}
					case 'selectWindowChanged':
						this.selectIndex = data.playIndex
						break

					// 异常
					case 'errorInfo':
						// console.error('err data from receiveMessageFromWSPlayer', data)
						// if (data.errorData && data.errorData.apiErrorInfo && data.errorData.apiErrorInfo.response && data.errorData.apiErrorInfo.response.status && data.errorData.apiErrorInfo.response.status > 400 && data.errorData.apiErrorInfo.response.status < 404) {
						//   window.dispatchEvent(new CustomEvent('unauthorized'))
						// } else {
						//   $.message({
						//       type: 'error',
						//       message: data.errorInfo || '错误信息提示'
						//   })
						// }
						break
					default:
						break
				}

				options.playerAction && options.playerAction(type, data)
			}
		})

		// console.log('🚀 ~ DahuaPlayer ~ createPlayer ~ this.player:', this.player)
	}

	/**
	 * 播放器重载
	 */
	reset(el, options = {}) {
		// 销毁播放实例，重置播放器
		if (this.player) {
			this.destroy()
		}

		this.createPlayer(el, options)
	}

	/**
	 * 销毁播放器
	 * 关闭全部窗口，并移除监听事件，用于销毁播放器，释放内存
	 */
	destroy() {
		clearInterval(this.loopKeepAliveTimer)

		if (this.player) {
			try {
				this.player.dispose()
				this.player.destroy()
				this.player = null
			} catch (error) {
				console.log('🚀 ~ destroy ~ error:', error)
			}
		}
	}

	// 等待实例初始化完成，完成后执行回调
	waitInitializationCompleted(callback) {
		if (!this.player) {
			console.log('大华播放器没有初始化完成')

			return
		}

		callback && callback()
	}

	// rtsp 播放
	playByRtsp() {
		this.waitInitializationCompleted(() => {

		})
	}

	/**
	 * 播放实时视频
	 * eq. {
	 * channelList : [
	 *    {
	 *      channelCode : 'xxxx',
	 *      isOnline : true,
	 *      cameraType : 2 ,
	 *    } 
	 *  ],
	 *  streamType :1,
	 *  windowIndex : 0,
	 *  searchOnline : false
	 * @param {Object[]} channelList 
	 * @param {String}   channelList.channelCode  通道编码 code
	 * @param {Boolean}  channelList.isOnline     是否在线，false 时不会去获取 rtsp 地址和拉流
	 * @param {Number}   channelList.cameraType   相机类型  [1:枪机, 2:球机, 3:半球机]
	 * @param {Number}   streamType   码流类型 [1:主码流, 2:辅码流1, 3:辅码流2] 默认为 2:辅码流1
	 * @param {Number}   [windowIndex]  窗口索引 默认为当前的已选窗口
	 * @param {Boolean}  searchOnline 是否组件内部调用 vsl 接口获取通道的在线状态，会覆盖 channelList 的 isOnline
	 */
	playRealVideo({ channelList, streamType, windowIndex }) {
		console.log('🚀 ~ playRealVideo ~ channelList, windowIndex:', channelList, windowIndex)
		if (channelList.length < 1) {
			console.log('channelList 为空')

			return
		}

		this.waitInitializationCompleted(() => {
			// console.log('🚀 ~ dahua sdk playRealVideo')
			this.player.playRealVideo({
				channelList,
				streamType,
				windowIndex: windowIndex,
				searchOnline: true
			})
		})
	}

	/**
	 * 播放录像
	 * eq. {
	 * channelList : [
	 *    {
	 *      channelCode : 'xxxx',
	 *      isPause : true
	 *    } 
	 *  ],
	 *  streamType :1,
	 *  windowIndex : 0,
	 *  searchOnline : false
	 * @param {Object[]}   channelList 
	 * @param {String}     channelList.channelCode      通道编码 code
	 * @param {Boolean}   [channelList.isPause=true]  视频初始化是否暂停，默认暂停
	 * @param {Timestamp}  startTime   录像开始时间，单位: 秒
	 * @param {Timestamp}  endTime     录像结束时间，单位: 秒，如果 startTime 和 endTIme 不是同一天时，以有录像的第一天进行播放
	 * @param {Number}    [recordSource=2] 存储位置类型包括 [2:中心录像, 3:设备录像], 默认为 2
	 */
	playRecordVideo({ channelList, startTime, endTime, recordSource }) {
		if (channelList.length < 1) {
			console.log('channelList 为空')

			return
		}

		console.log('🚀 ~ playRecordVideo ~ ', {
		  channelList,
		  startTime,
		  endTime: endTime || Date.now() / 1000,
		  recordSource
		})

		this.waitInitializationCompleted(() => {
			this.player.playRecordVideo({
				channelList,
				startTime,
				isPause: false,
				endTime: endTime || Date.now() / 1000,
				recordSource
			})
		})
		
		// console.log('🚀 ~ //this.waitInitializationCompleted ~ this.player.playRecordVideo:', this.player.playRecordVideo)
	}

	/**
	 * 播放选中窗口的视频
	 * @param {Number} index 要播放的窗口的索引，不传时当前选中的窗口开始播放
	 */
	play(index) {
		this.waitInitializationCompleted(() => {
			this.player.play(index)
		})
	}

	/**
	 * 暂停选中窗口的视频
	 * @param {Number} index 要暂停的窗口的索引，不传时当前选中的窗口暂停播放
	 */
	pause(index) {
		this.waitInitializationCompleted(() => {
			this.player.pause(index)
		})
	}

	/**
	 * 关闭选中窗口的视频
	 * @param {Number} index 要关闭窗口的索引，index 不传时关闭所有窗口
	 */
	close(index) {
		this.waitInitializationCompleted(() => {
			this.player.close(index)
		})
	}

	/**
	 * 设置全屏
	 */
	setFullScreen() {
		this.waitInitializationCompleted(() => {
			this.player.setFullScreen()
		})
	}

	/**
	 * 设置窗口显示模式, 自适应还是拉伸充满窗口
	 * @param {String} playerAdapter [selfAdaption: 为自适应, stretching:为拉伸]
	 */
	setPlayerAdapter(playerAdapter) {
		this.waitInitializationCompleted(() => {
			this.player.setPlayerAdapter(playerAdapter)
		})
	}

	/**
	 * 设置窗口内视频是自适应还是拉伸充满窗口
	 * @param {Number|String} playerAdapter [1: 自适应, 2:拉伸, selfAdaption: 自适应, stretching:拉伸]
	 */
	setPlayerAdapter(playerAdapter) {
		switch (playerAdapter) {
			// 自适应
			case 1:
				playerAdapter = 'selfAdaption'
				break

			// 拉伸
			case 2:
				playerAdapter = 'stretching'
				break
		}

		this.waitInitializationCompleted(() => {
			this.player.setPlayerAdapter(playerAdapter)
		})
	}

	/**
	 * 设置窗口个数
	 * @param {String} number 窗口的个数, 目前可设置 1、2、3、4、6、8、9、16、25 等，该值不能超出 PlayerManager 方法的 maxNum
	 */
	setPlayerNum(number) {
		const arrowNumber = {
			1: true,
			2: true,
			3: true,
			4: true,
			6: true,
			8: true,
			9: true,
			16: true,
			25: true
		}

		if (!arrowNumber[number]) {
			throw new Error('设置的数字只能是 1、2、3、4、6、8、9、16、25')
		}

		this.waitInitializationCompleted(() => {
			this.player.setPlayerNum(number)

			this.maxPlayerNumber = number
		})
	}

	/**
	 * 设置选中窗口的索引
	 * @param {String} index 要设置为选中状态窗口的索引
	 */
	setSelectIndex(index) {
		if (index >= 0 && index < this.maxPlayerNumber) {
			this.waitInitializationCompleted(() => {
				this.player.setSelectIndex(index)
				this.selectIndex = index
			})
		} else {
			throw new Error(`index 不在可用范围内，最大可使用 index 为 ${this.maxPlayerNumber - 1}`)
		}
	}

	/**
	 * 在当前选中窗口中，跳转到指定时间节点播放录像，该时间点无录像时通过播放器的 receiveMessageFromWSPlayer 事件回调返回信息
	 * @param {String} time 要跳转的时间节点，格式为 HH:mm:ss
	 */
	jumpPlayByTime(time) {
		this.waitInitializationCompleted(() => {
			this.player.jumpPlayByTime(time)
		})
	}

	/**
	 * 在指定窗口中如果录像在播放，可设置录像回放播放倍速
	 * speed 如果是 0.125、8，音频不支持播放
	 * @param {Number} speed 指定窗口中如果有录像在播放，可以设置不同的倍速进行播放， 共有 0.125、0.25、0.5、1、1.25、1.5、2、4、8 等 9 种倍速
	 * @param {Number} index 要设置倍速的窗口索引
	 */
	playSpeed(speed, index) {
		this.waitInitializationCompleted(() => {
			this.player.playSpeed(speed, index)
		})
	}

	/**
	 * 在指定窗口中，如果有录像在播放，可以进行抓图下载
	 * @param {Number} index 窗口序号索引
	 */
	picCap(index) {
		this.waitInitializationCompleted(() => {
			this.player.picCap(index)
		})
	}

	/**
	 * 在指定窗口中，获取 base64 格式抓图数据
	 * @param {Number} index 窗口序号索引
	 */
	getPicCapBase64(index) {
		this.waitInitializationCompleted(() => {
			this.player.getPicCapBase64(index)
		})
	}

	/**
	 * 开启指定窗口/选中窗口的声音
	 * @param {Number} [index] 窗口序号索引，不传时为当前选中的窗口索引
	 */
	openVolume(index) {
		this.waitInitializationCompleted(() => {
			this.player.openVolume(index)
		})
	}

	/**
	 * 关闭指定窗口/选中窗口的声音
	 * @param {Number} [index] 窗口序号索引，不传时为当前选中的窗口索引
	 */
	closeVolume(index) {
		this.waitInitializationCompleted(() => {
			this.player.closeVolume(index)
		})
	}

	/**
	 * 设置指定窗口的音频播放音量
	 * @param {Number} index 窗口序号索引
	 * @param {Number} volume 音量，值为 0-1 之间一位小数的浮点数如: 0.1、0.2......0.9
	 */
	setVolume(index, volume) {
		this.waitInitializationCompleted(() => {
			this.player.setVolume(index, volume)
		})
	}

	/**
	 * 指定窗口开始录制本地录像，同单击视频窗口上方操作栏本地录像按钮功能一致
	 * @param {Number} index 窗口序号索引
	 * @param {Number} [size] 单个录像文件大小(单位 M)，不传时按实例化时配置的 localRecordSize 大小进行录制
	 */
	startLocalRecord(index, size) {
		this.waitInitializationCompleted(() => {
			this.player.startLocalRecord(index, size)
		})
	}

	/**
	 * 指定窗口停止录制本地录像，同单击视频窗口上方操作栏本地录像按钮功能一致
	 * @param {Number} index 窗口序号索引
	 */
	stopLocalRecord(index) {
		this.waitInitializationCompleted(() => {
			this.player.stopLocalRecord(index)
		})
	}
}

export default DahuaPlayer